from flask import Flask, render_template, request, jsonify
import time
from datetime import datetime, timezone, timedelta
import concurrent.futures
from utils.prometheus_client import PrometheusClient
from utils.data_processor import (
    get_deployments_from_prod,
    get_images_and_runtime_from_uat_batch,
    compare_images,
    format_creation_time,  # 修改：使用format_creation_time替代calculate_runtime
    PROD_NAMESPACE,
    PROMETHEUS_URLS
)

app = Flask(__name__)

# 添加缓存机制
cache = {}
CACHE_TIMEOUT = 3  # 3秒缓存


def get_beijing_time():
    """获取当前北京时间"""
    beijing_time = datetime.now(timezone(timedelta(hours=8)))
    return beijing_time.strftime("%Y-%m-%d %H:%M:%S")


def get_deployment_data():
    """获取部署数据（从缓存或实时查询）"""
    # 创建两个环境的客户端
    clients = {
        "216": PrometheusClient(PROMETHEUS_URLS["216"]),
        "prod": PrometheusClient(PROMETHEUS_URLS["prod"])
    }

    # 从生产环境获取deployment列表
    deployments = get_deployments_from_prod(clients["prod"], PROD_NAMESPACE)

    data = []
    if deployments:
        # 使用线程池并行获取生产环境镜像和创建时间
        with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
            # 获取生产环境镜像
            prod_futures = {executor.submit(clients["prod"].get_images_from_env, dep, PROD_NAMESPACE): dep for dep in
                            deployments}
            prod_images_map = {}
            for future in concurrent.futures.as_completed(prod_futures):
                dep = prod_futures[future]
                try:
                    prod_images_map[dep] = future.result()
                except Exception as e:
                    print(f"Error getting production images for {dep}: {e}")
                    prod_images_map[dep] = ["Error"]

            # 获取生产环境创建时间
            prod_runtime_futures = {executor.submit(clients["prod"].get_deployment_creation_time, dep, PROD_NAMESPACE): dep for dep in deployments}
            prod_runtime_map = {}
            for future in concurrent.futures.as_completed(prod_runtime_futures):
                dep = prod_runtime_futures[future]
                try:
                    creation_time = future.result()
                    # 修改：使用format_creation_time格式化创建时间
                    prod_runtime_map[dep] = format_creation_time(creation_time) if creation_time else "未知"
                except Exception as e:
                    print(f"Error getting production creation time for {dep}: {e}")
                    prod_runtime_map[dep] = "未知"

        # 批量获取UAT环境镜像和创建时间
        uat_data_map = get_images_and_runtime_from_uat_batch(clients["216"], deployments)

        for dep in deployments:
            images_prod = prod_images_map.get(dep, ["Error"])
            runtime_prod = prod_runtime_map.get(dep, "未知")
            uat_result = uat_data_map.get(dep, {"images": ["Not Found"], "runtime": "未知"})
            images_uat = uat_result["images"]
            runtime_uat = uat_result["runtime"]

            # 确定状态
            if images_uat == ["Not Found"]:
                status_flag = "not_found"
            elif compare_images(images_prod, images_uat):
                status_flag = "match"
            else:
                status_flag = "diff"

            data.append({
                "name": dep,
                "images_prod": images_prod,
                "runtime_prod": runtime_prod,  # 这里已经是格式化后的日期时间
                "images_uat": images_uat,
                "runtime_uat": runtime_uat,    # 这里已经是格式化后的日期时间
                "status": status_flag,
                "namespace": uat_result.get("namespace", "Not Found"),
                "deployment_uat": uat_result.get("deployment", dep),
                "suffix": uat_result.get("suffix", "")
            })

    return data


@app.route("/")
def index():
    # 获取查询参数
    status_filter = request.args.get('status', 'all')
    search_query = request.args.get('search', '')

    # 检查缓存
    cache_key = f"data_{status_filter}_{search_query}"
    cached_data = cache.get(cache_key)

    if cached_data and time.time() - cached_data['timestamp'] < CACHE_TIMEOUT:
        # 更新缓存数据的时间显示为北京时间
        cached_data['data']['update_time'] = get_beijing_time()
        return render_template("index.html", **cached_data['data'])

    # 创建两个环境的客户端
    clients = {
        "216": PrometheusClient(PROMETHEUS_URLS["216"]),
        "prod": PrometheusClient(PROMETHEUS_URLS["prod"])
    }

    # 检查连接状态
    status = {}
    for env, client in clients.items():
        try:
            test_query = 'up'
            result = client.query(test_query)
            status[env] = "连接正常" if result is not None else "连接异常"
        except Exception as e:
            status[env] = f"连接异常: {str(e)}"

    # 获取部署数据
    deployment_data = get_deployment_data()

    # 处理数据用于前端显示
    processed_data = []
    match_count = 0
    diff_count = 0
    not_found_count = 0

    for d in deployment_data:
        # 确定状态并计数
        if d["status"] == "not_found":
            not_found_count += 1
        elif d["status"] == "match":
            match_count += 1
        else:
            diff_count += 1

        processed_data.append({
            "name": d["name"],
            "images_prod": "; ".join(d["images_prod"]),
            "runtime_prod": d["runtime_prod"],  # 直接显示格式化后的日期时间
            "images_uat": "; ".join(d["images_uat"]),
            "runtime_uat": d["runtime_uat"],    # 直接显示格式化后的日期时间
            "status": d["status"]
        })

    # 按状态排序：一致 > 不一致 > 未找到
    status_order = {"match": 0, "diff": 1, "not_found": 2}
    processed_data.sort(key=lambda x: (status_order[x["status"]], x["name"]))

    # 应用搜索过滤
    if search_query:
        processed_data = [d for d in processed_data if search_query.lower() in d["name"].lower()]

    # 应用状态过滤
    if status_filter != 'all':
        processed_data = [d for d in processed_data if d["status"] == status_filter]

    template_data = {
        "data": processed_data,
        "namespace": PROD_NAMESPACE,
        "update_time": get_beijing_time(),  # 使用北京时间
        "prom_216_status": status["216"],
        "prom_prod_status": status["prod"],
        "total_count": len(processed_data),
        "match_count": match_count,
        "diff_count": diff_count,
        "not_found_count": not_found_count,
        "PROMETHEUS_URLS": PROMETHEUS_URLS,
        "PROD_NAMESPACE": PROD_NAMESPACE,
        "status_filter": status_filter,
        "search_query": search_query
    }

    # 更新缓存
    cache[cache_key] = {
        'timestamp': time.time(),
        'data': template_data
    }

    return render_template("index.html", **template_data)


@app.route("/metrics")
def metrics():
    """提供部署镜像数据的API接口"""
    try:
        deployment_data = get_deployment_data()

        # 格式化数据用于API响应
        metrics_data = []
        for d in deployment_data:
            metrics_data.append({
                "deployment": d["name"],
                "production_images": d["images_prod"],
                "production_creation_time": d["runtime_prod"],  # 修改字段名
                "uat_images": d["images_uat"],
                "uat_creation_time": d["runtime_uat"],          # 修改字段名
                "status": d["status"],
                "uat_namespace": d["namespace"],
                "uat_deployment": d["deployment_uat"],
                "suffix": d["suffix"]
            })

        return jsonify({
            "success": True,
            "data": metrics_data,
            "timestamp": get_beijing_time(),  # 使用北京时间
            "total_count": len(metrics_data)
        })

    except Exception as e:
        return jsonify({
            "success": False,
            "error": str(e),
            "timestamp": get_beijing_time()  # 使用北京时间
        }), 500


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5005, debug=True)